package com.hyx.api.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hyx.api.domain.*;
import com.hyx.api.domain.bo.*;
import com.hyx.api.domain.vo.*;
import com.hyx.api.enums.*;
import com.hyx.api.mapper.*;
import com.hyx.api.service.IAppShopService;
import com.hyx.api.service.pc_admin.IRecycleOrderService;
import com.hyx.api.utils.GenSerialNoUtil;
import com.hyx.api.utils.base.MobileBaseService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.SysDictDataMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class IAppShopServiceImpl implements IAppShopService {

    private final MobileBaseService mobileBaseService;

    private final SysDictTypeDaoMapper dictTypeDaoMapper;

    private final SysDictDataMapper dictDataMapper;

    private final ModelMapper modelMapper;

    private final VerifyModelOptionMapper verifyModelOptionMapper;

    private final InquiryOrderMapper inquiryOrderMapper;

    private final FileUploadMapper uploadMapper;

    private final OfferOrderMapper offerOrderMapper;

    private final UserMapper userMapper;

    private final RecycleBusinessMapper recycleBusMapper;

    private final RecycleOrderMapper recycleOrderMapper;

    private final RefundOrderMapper refundOrderMapper;

    private final CompanyRecoverInfoMapper companyRecoverInfoMapper;

    private final SpreadOrderMapper spreadOrderMapper;

    private final PriceDownFormulaMapper priceDownFormulaMapper;

    private final CompanyMapper companyMapper;

    private final MsgDialogueOrderMapper msgDialogueMapper;

    private final IRecycleOrderService recycleOrderService;

    private final RecycleReceivingAddrMapper receivingAddrMapper;

    @Override
    public AjaxResult queryTypeList() {
        QueryWrapper<SysDictType> dictTypeWrapper = new QueryWrapper<>();
        dictTypeWrapper.like("dict_type", "mill_type_%");
        //正常
        dictTypeWrapper.eq("status", 0);
        return AjaxResult.success(dictTypeDaoMapper.selectList(dictTypeWrapper));
    }

    @Override
    public AjaxResult queryTypeDataList(String dictType) {
        return AjaxResult.success(dictDataMapper.selectDictDataByType(dictType));
    }

    @Override
    public void insertVerifyModelOption(VerifyModelOptionBo bo) {
        if (bo.getParentId() != null) {
            VerifyModelOption parentVerify = verifyModelOptionMapper.selectById(bo.getParentId());
            if (parentVerify == null) {
                throw new ServiceException("父级标题不存在");
            }
        }
        SysDictType dictType = dictTypeDaoMapper.selectById(bo.getModelTypes());
        if (dictType == null) {
            throw new ServiceException("没有该机型，请核实");
        }
        QueryWrapper<VerifyModelOption> verifyWrapper = new QueryWrapper<>();
        verifyWrapper.eq("parent_id", bo.getParentId()).eq("name", bo.getName());
        Long count = verifyModelOptionMapper.selectCount(verifyWrapper);
        if (count > 0) {
            throw new ServiceException("已经存在，不能重复添加");
        }
        VerifyModelOption insertDO = new VerifyModelOption();
        BeanUtils.copyProperties(bo, insertDO);
        verifyModelOptionMapper.insert(insertDO);
    }

    @Override
    public void updateVerifyModelOption(VerifyModelOptionBo bo) {
        VerifyModelOption verifyModelOption = tranEntityBeforeSave(bo);
        verifyModelOptionMapper.updateById(verifyModelOption);
    }

    @Override
    public void deleteVerifyModelOptionByIds(Long[] ids) {
        List<VerifyModelOption> list = new ArrayList<>();
        for (Long id : ids) {
            VerifyModelOption verifyModelOption = new VerifyModelOption();
            verifyModelOption.setDelFlag(2);
            verifyModelOption.setId(id);
            list.add(verifyModelOption);
        }
        verifyModelOptionMapper.updateBatchById(list);
    }

    @Override
    public AjaxResult queryVerifyOptions(Integer modelTypeId) {
        List<VerifyModelOptionBaseVo> resList = new ArrayList<>();
        QueryWrapper<VerifyModelOption> verifyWrapper = new QueryWrapper<>();
        verifyWrapper.eq("model_type_id", modelTypeId).eq("status", YesNoEnum.YES.code())
                .eq("del_flag", YesNoEnum.NO.code());
        List<VerifyModelOption> list = verifyModelOptionMapper.selectList(verifyWrapper);
        List<VerifyModelOption> parentList = list.stream().filter(s -> s.getParentId() == null).collect(Collectors.toList());
        for (VerifyModelOption parentVerify : parentList) {
            VerifyModelOptionBaseVo baseRes = new VerifyModelOptionBaseVo();
            baseRes.setTitle(parentVerify.getName());
            for (VerifyModelOption verify : list) {
                if (verify.getId().equals(parentVerify.getId())) {
                    continue;
                }
                if (verify.getParentId().equals(parentVerify.getId())) {
                    VerifyModelOptionVo verifyDO = new VerifyModelOptionVo();
                    BeanUtils.copyProperties(verify, verifyDO);
                    baseRes.getList().add(verifyDO);
                }
            }
            resList.add(baseRes);
        }
        return AjaxResult.success(resList);
    }

    @Override
    public int insertInquiryOrder(InquiryOrderBo bo) {
        User user = mobileBaseService.hasLogin();
        InquiryOrder inquiryOrder = tranEntityBeforeSave(bo);
        validEntityBeforeSave(inquiryOrder);
        inquiryOrder.setUserId(user.getId());
        inquiryOrder.setCreateTime(new Date());
        return inquiryOrderMapper.insert(inquiryOrder);
    }

    @Transactional
    @Override
    public AjaxResult inquiryBindOfferOrder(Long inquiryOrderId, Long offerOrderId) {
        //获取当前用户信息
        User user = mobileBaseService.hasLogin();
        InquiryOrder inquiryOrder = inquiryOrderMapper.selectById(inquiryOrderId);
        if (inquiryOrder == null)
            return AjaxResult.error("数据错误");
        OfferOrder offerOrder = offerOrderMapper.selectById(offerOrderId);
        if (offerOrder == null)
            return AjaxResult.error("数据错误");

        //询价订单中标id修改
        inquiryOrder.setOfferId(offerOrderId);
        inquiryOrderMapper.updateById(inquiryOrder);
        //中标数据设置
        offerOrder.setIsSuccessful(1);
        offerOrderMapper.updateById(offerOrder);

        //创建回收订单
        LambdaQueryWrapper<RecycleOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(RecycleOrder::getInquiryOrderId, inquiryOrderId);
        Long count = recycleOrderMapper.selectCount(lqw);
        if (count > 0)
            return AjaxResult.error("已创建");
        RecycleOrder recycleOrder = new RecycleOrder();
        recycleOrder.setInquiryOrderId(inquiryOrderId);
        recycleOrder.setCode(GenSerialNoUtil.genOrderSn(SnTypeEnum.PAY));
        recycleOrder.setRecycleBusId(offerOrder.getOfferBusId());
        recycleOrder.setPrice(offerOrder.getOfferPrice());
        recycleOrder.setRecycleOperatorId(offerOrder.getOfferOperatorId());
        User shopUser = userMapper.selectById(inquiryOrder.getUserId());
        recycleOrder.setShopId(shopUser.getStoreId());
        recycleOrder.setCompanyId(shopUser.getCompanyId());
        recycleOrder.setOperatorId(shopUser.getId());
        recycleOrder.setStatus(RecycleOrderStatusEnum.NO_PAY.code());
        LambdaQueryWrapper<RecycleReceivingAddr> addrWrapper = Wrappers.lambdaQuery();
        addrWrapper.eq(RecycleReceivingAddr::getRecycleBusId, offerOrder.getOfferBusId());
        List<RecycleReceivingAddr> receivingAddrs = receivingAddrMapper.selectList(addrWrapper);
        if (!receivingAddrs.isEmpty()) {
            recycleOrder.setReceivingAddrId(receivingAddrs.get(0).getId());
        }
        int num = recycleOrderMapper.insert(recycleOrder);
        return num > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    public AjaxResult recycleOrderStaUpdate(RecOrderStaUpdateBo bo) {
        RecycleOrder recycleOrder = recycleOrderMapper.selectById(bo.getId());
        if (recycleOrder == null) {
            return AjaxResult.error("没有该回收订单，请核实");
        }
        recycleOrder.setStatus(bo.getStatus());
        if (bo.getStatus().equals(RecycleOrderStatusEnum.FINISH.code())) {
            return AjaxResult.error("状态错误");
        } else if (bo.getStatus().equals(RecycleOrderStatusEnum.NO_RECEIVING.code())) {
            if (StringUtils.isEmpty(bo.getExpressageNo())) {
                return AjaxResult.error("参数错误，修改失败");
            } else {
                recycleOrder.setExpressageNo(bo.getExpressageNo());
                recycleOrder.setShipmentsTime(bo.getShipmentsTime() == null ? new Date() : bo.getShipmentsTime());
            }
        } else if (bo.getStatus().equals(RecycleOrderStatusEnum.CANCEL.code())) {
            recycleOrder.setRemark(StringUtils.isEmpty(bo.getRemark()) ? null : bo.getRemark());
        }
        recycleOrderMapper.updateById(recycleOrder);
        return AjaxResult.success();
    }

    @Override
    public AjaxResult queryShopNoHandleOrderList() {
        User user = mobileBaseService.hasLogin();
        return AjaxResult.success(recycleOrderMapper.queryShopNoHandleOrderList(user.getId()));
    }

    @Override
    public AjaxResult queryShopNoHandleOrderDetail(Long recycleOrderId) {
        RecycleOrder recycleOrder = recycleOrderMapper.selectById(recycleOrderId);
        if (recycleOrder == null) {
            return AjaxResult.error("该回收订单不存在，请核实");
        }
        RecycleOrderVo recycleOrderVo = new RecycleOrderVo();
        BeanUtils.copyProperties(recycleOrder, recycleOrderVo);
        RecycleReceivingAddr receivingAddr = receivingAddrMapper.selectById(recycleOrder.getReceivingAddrId());
        if (receivingAddr != null) {
            recycleOrderVo.setReceivingAddr(receivingAddr.getFullAddr());
            recycleOrderVo.setReceivingName(receivingAddr.getContactName());
            recycleOrderVo.setReceivingMobile(receivingAddr.getContactMobile());
        }
        InquiryOrder inquiryOrder = inquiryOrderMapper.selectById(recycleOrder.getInquiryOrderId());
        OfferOrder offerOrder = offerOrderMapper.selectById(inquiryOrder.getOfferId());
        QueryWrapper<RefundOrder> refundWrapper = new QueryWrapper<>();
        refundWrapper.eq("recycle_order_id", recycleOrderId);
        RefundOrder refundOrder = refundOrderMapper.selectOne(refundWrapper);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("recycleOrder", recycleOrderVo);
        jsonObject.put("inquiryOrder", inquiryOrder);
        jsonObject.put("offerOrder", offerOrder);
        if (refundOrder != null) {
            jsonObject.put("refundOrder", refundOrder);
        }
        return AjaxResult.success(jsonObject);
    }

    @Override
    public AjaxResult queryInquiringList() {
        User user = mobileBaseService.hasLogin();
        List<InquiryOrderVo> resList = new ArrayList<>();
        LambdaQueryWrapper<InquiryOrder> lqw = Wrappers.lambdaQuery();
        if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OPERATOR.code())) {
            lqw.eq(InquiryOrder::getUserId, user.getId());
        } else if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OWNER.code())) {
            LambdaQueryWrapper<User> userWrapper = Wrappers.lambdaQuery();
            userWrapper.eq(User::getStoreId, user.getStoreId());
            List<User> users = userMapper.selectList(userWrapper);
            if (!users.isEmpty()) {
                lqw.in(InquiryOrder::getUserId, users.stream().map(User::getId).collect(Collectors.toList()));
            }
        } else if (Objects.equals(user.getType(), UserTypeEnum.COMPANY.code())) {
            LambdaQueryWrapper<User> userWrapper = Wrappers.lambdaQuery();
            userWrapper.eq(User::getCompanyId, user.getCompanyId());
            List<User> users = userMapper.selectList(userWrapper);
            if (!users.isEmpty()) {
                lqw.in(InquiryOrder::getUserId, users.stream().map(User::getId).collect(Collectors.toList()));
            }
        }
        DateTime startTime = DateUtil.offsetMinute(new Date(), -10);
        lqw.ge(InquiryOrder::getCreateTime, startTime);
        lqw.isNull(InquiryOrder::getOfferId);
        List<InquiryOrder> vos = inquiryOrderMapper.selectList(lqw);
        for (InquiryOrder vo : vos) {
            LambdaQueryWrapper<MsgDialogueOrder> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(MsgDialogueOrder::getInquiryOrderId, vo.getId());
            wrapper.eq(MsgDialogueOrder::getIsRead, YesNoEnum.NO.code());
            wrapper.eq(MsgDialogueOrder::getReceiveUser, user.getId());
            InquiryOrderVo resDO = new InquiryOrderVo();
            BeanUtils.copyProperties(vo, resDO);
            resDO.setMsgNoReadCount(msgDialogueMapper.selectCount(wrapper));
            resList.add(resDO);
        }
        return AjaxResult.success(resList);
    }

    @Override
    public AjaxResult queryInquiryAllList(Integer status) {
        User user = mobileBaseService.hasLogin();
        if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OPERATOR.code())) {
            return AjaxResult.success(inquiryOrderMapper.queryInquiryListByUser(
                    user.getId(), null, null, status));
        } else if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OWNER.code())) {
            return AjaxResult.success(inquiryOrderMapper.queryInquiryListByUser(
                    null, user.getStoreId(), null, status));
        } else if (Objects.equals(user.getType(), UserTypeEnum.COMPANY.code())) {
            return AjaxResult.success(inquiryOrderMapper.queryInquiryListByUser(
                    null, null, user.getCompanyId(), status));
        } else {
            return AjaxResult.error("没有权限");
        }
    }

    @Override
    public AjaxResult queryShopBindRecycleBusList(String keyword) {
        User user = mobileBaseService.hasLogin();
        return AjaxResult.success(companyRecoverInfoMapper.queryShopBindRecycleList(keyword, user.getCompanyId()));
    }

    @Override
    public AjaxResult updateRefundOrderStatus(Long refundOrderId, Integer status) {
        User user = mobileBaseService.hasLogin();
        RefundOrder refundOrder = refundOrderMapper.selectById(refundOrderId);
        if (refundOrder == null) {
            return AjaxResult.error("没有该退单记录，修改失败");
        }
        RecycleOrder recycleOrder = recycleOrderMapper.selectById(refundOrder.getRecycleOrderId());
//        if (!recycleOrder.getCompanyId().equals(user.getCompanyId())) {
//            return AjaxResult.error("请勿操作其余门店的订单");
//        }
        if (status.equals(RefundStatusEnum.AUDITING.code())) {
            return AjaxResult.error("状态错误，修改失败");
        }
        refundOrder.setStatus(status);
        refundOrderMapper.updateById(refundOrder);
        if (Objects.equals(status, RefundStatusEnum.REFUND_FINISH.code())) {
            recycleOrder.setStatus(RecycleOrderStatusEnum.ALREADY_REFUND.code());
            recycleOrderMapper.updateById(recycleOrder);
        }
        return AjaxResult.success();
    }

    @Override
    public List<ShopOrderListVo> queryRefundOrderList(ShopRefOrderQueBo req) {
        User user = mobileBaseService.hasLogin();
        List<ShopOrderListVo> orderListVos;
        if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OPERATOR.code())) {
            orderListVos = refundOrderMapper.queryRefundOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), user.getStoreId(),
                    user.getId(), null);
        } else if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OWNER.code())) {
            orderListVos = refundOrderMapper.queryRefundOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), user.getStoreId(),
                    null, null);
        } else if (Objects.equals(user.getType(), UserTypeEnum.COMPANY.code())) {
            orderListVos = refundOrderMapper.queryRefundOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), null,
                    null, user.getCompanyId());
        } else {
            return new ArrayList<>();
        }

        for (ShopOrderListVo orderListVo : orderListVos) {
            InquiryOrder inquiryOrder = inquiryOrderMapper.selectById(orderListVo.getInquiryOrderId());
            List<VerifyModelOption> options = verifyModelOptionMapper.selectBatchIds(Arrays.asList(inquiryOrder.getVerifyModelIds().split(",")));
            orderListVo.setSpecs(options.stream().filter(s -> s.getType() == 1).map(VerifyModelOption::getName).collect(Collectors.joining(",")));
            List<FileUpload> files = uploadMapper.selectBatchIds(Arrays.asList(inquiryOrder.getFileIds().split(",")));
            List<String> fileUrls = files.stream().map(FileUpload::getUrl).collect(Collectors.toList());
            orderListVo.setFileUrls(fileUrls);
        }
        return orderListVos;
    }

    @Override
    public AjaxResult auditSpreadOrder(SpreadOrderBo bo) {
        if (bo.getId() == null) {
            return AjaxResult.error("参数错误，无法修改该订单");
        }
        SpreadOrder spreadOrder = spreadOrderMapper.selectById(bo.getId());
        if (spreadOrder == null) {
            return AjaxResult.error("没有该订单，修改失败");
        }
        spreadOrder.setStatus(bo.getStatus());
        if (bo.getStatus().equals(SpreadStatusEnum.HANDLING.code())) {
            if (StringUtils.isEmpty(bo.getPayImg())) {
                return AjaxResult.error("请提交截图");
            }
            spreadOrder.setPayImg(bo.getPayImg());
        } else if (!bo.getStatus().equals(SpreadStatusEnum.SPREAD_FAIL.code())) {
            log.error("审核追差订单时，状态传递错误，传递状态为：{}", bo.getStatus());
            return AjaxResult.error("参数错误，无法修改");
        }
        spreadOrderMapper.updateById(spreadOrder);
        return AjaxResult.success("追差订单处理成功");
    }

    @Override
    public List<ShopOrderListVo> querySpreadOrderList(ShopSpreadQueBo req) {
        User user = mobileBaseService.hasLogin();
        List<ShopOrderListVo> orderListVos;
        if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OPERATOR.code())) {
            orderListVos = spreadOrderMapper.querySpreadOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), user.getStoreId(),
                    user.getId(), null);
        } else if (Objects.equals(user.getType(), UserTypeEnum.SHOP_OWNER.code())) {
            orderListVos = spreadOrderMapper.querySpreadOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), user.getStoreId(),
                    null, null);
        } else if (Objects.equals(user.getType(), UserTypeEnum.COMPANY.code())) {
            orderListVos = spreadOrderMapper.querySpreadOrderList(req.getStatus(), req.getRecoverBusId(),
                    req.getStartAmount(), req.getEndAmount(), req.getKeyword(), null,
                    null, user.getCompanyId());
        } else {
            return new ArrayList<>();
        }

        for (ShopOrderListVo orderListVo : orderListVos) {
            InquiryOrder inquiryOrder = inquiryOrderMapper.selectById(orderListVo.getInquiryOrderId());
            List<VerifyModelOption> options = verifyModelOptionMapper.selectBatchIds(Arrays.asList(inquiryOrder.getVerifyModelIds().split(",")));
            orderListVo.setSpecs(options.stream().filter(s -> s.getType() == 1).map(VerifyModelOption::getName).collect(Collectors.joining(",")));
            List<FileUpload> files = uploadMapper.selectBatchIds(Arrays.asList(inquiryOrder.getFileIds().split(",")));
            List<String> fileUrls = files.stream().map(FileUpload::getUrl).collect(Collectors.toList());
            orderListVo.setFileUrls(fileUrls);
        }
        return orderListVos;
    }

    @Override
    public AjaxResult queryShopSendCountInfo() {
        User user = mobileBaseService.hasLogin();
        ShopSendCountVo res = new ShopSendCountVo();

        CountAmountDao waitSendDao = recycleOrderMapper.queryCountAndAmountByStaShop(user.getStoreId(),
                SendGoodsStatusEnum.WAIT_SEND.code());
        res.setWaitSendCount(waitSendDao.getCount());
        res.setWaitSendAmount(waitSendDao.getAmount());

        CountAmountDao waitSignForDao = recycleOrderMapper.queryCountAndAmountByStaShop(user.getStoreId(),
                SendGoodsStatusEnum.WAIT_SIGN_FOR.code());
        res.setWaitSignForCount(waitSignForDao.getCount());
        res.setWaitSignForAmount(waitSignForDao.getAmount());

        CountAmountDao timeoutSendDao = recycleOrderMapper.queryCountAndAmountByStaShop(user.getStoreId(),
                SendGoodsStatusEnum.TIMEOUT_SEND.code());
        res.setTimeoutSendCount(timeoutSendDao.getCount());
        res.setTimeoutSendAmount(timeoutSendDao.getAmount());

        CountAmountDao signForExceptionDao = recycleOrderMapper.queryCountAndAmountByStaShop(user.getStoreId(),
                SendGoodsStatusEnum.SIGN_FOR_EXCEPTION.code());
        res.setSignForExceptionCount(signForExceptionDao.getCount());
        res.setSignForExceptionAmount(signForExceptionDao.getAmount());

        return AjaxResult.success(res);
    }

    @Override
    public AjaxResult queryShopStatistics(ShopStatisticsBo bo) {
        User user = mobileBaseService.hasLogin();
        bo.setShopId(user.getStoreId());
        if (bo.getEndTime().before(bo.getStartTime())) {
            return AjaxResult.error("参数错误");
        }
        ShopStatisticsVo resDO = new ShopStatisticsVo();
        Long diffTime = bo.getEndTime().getTime() - bo.getStartTime().getTime();
        Date lastStartTime = new Date(bo.getStartTime().getTime() - diffTime);

        Integer inquiryCount = 0, inquiryCountLast = 0;

        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            inquiryCount = inquiryOrderMapper.queryInquiryCountForTimeShop(bo.getStartTime(),
                    bo.getEndTime(), null, null, user.getCompanyId());
            inquiryCountLast = inquiryOrderMapper.queryInquiryCountForTimeShop(lastStartTime,
                    bo.getStartTime(), null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            inquiryCount = inquiryOrderMapper.queryInquiryCountForTimeShop(bo.getStartTime(),
                    bo.getEndTime(), bo.getShopId(), null, null);
            inquiryCountLast = inquiryOrderMapper.queryInquiryCountForTimeShop(lastStartTime,
                    bo.getStartTime(), bo.getShopId(), null, null);
        } else {
            return AjaxResult.error("权限不足");
        }

        resDO.setInquiryCount(inquiryCount);
        if (inquiryCount > inquiryCountLast) {
            if (inquiryCountLast == 0) {
                resDO.setInquiryCountThanOldTimeUp(inquiryCount);
            } else {
                resDO.setInquiryCountThanOldTimeUp(Math.round(((float) inquiryCount - inquiryCountLast) / (float) inquiryCountLast));
            }
        } else if (inquiryCount < inquiryCountLast) {
            resDO.setInquiryCountThanOldTimeUpDown(Math.round(((float) inquiryCountLast - inquiryCount) / (float) inquiryCountLast));
        } else {
            resDO.setInquiryCountThanOldTimeUp(0);
        }

        Integer turnoverCount = 0, turnoverCountLast = 0;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            turnoverCount = recycleOrderMapper.queryFinishCountForTimeShop(bo.getStartTime(),
                    bo.getEndTime(), null, null, user.getCompanyId());
            turnoverCountLast = recycleOrderMapper.queryFinishCountForTimeShop(lastStartTime,
                    bo.getStartTime(), null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            turnoverCount = recycleOrderMapper.queryFinishCountForTimeShop(bo.getStartTime(),
                    bo.getEndTime(), bo.getShopId(), null, null);
            turnoverCountLast = recycleOrderMapper.queryFinishCountForTimeShop(lastStartTime,
                    bo.getStartTime(), bo.getShopId(), null, null);
        }

        resDO.setTurnover(turnoverCount);
        if (turnoverCount > turnoverCountLast) {
            if (turnoverCountLast == 0) {
                resDO.setTurnoverThanOldTimeUp(turnoverCount);
            } else {
                resDO.setTurnoverThanOldTimeUp(Math.round((float) (turnoverCount - turnoverCountLast) / (float) turnoverCountLast));
            }
        } else if (turnoverCount < turnoverCountLast) {
            resDO.setTurnoverThanOldTimeDown(Math.round((float) (turnoverCountLast - turnoverCount) / (float) turnoverCountLast));
        } else {
            resDO.setTurnoverThanOldTimeUp(0);
        }

        if (inquiryCount == 0) {
            resDO.setTurnoverRate(0.0);
        } else {
            resDO.setTurnoverRate(new BigDecimal(turnoverCount).divide(new BigDecimal(inquiryCount),
                    2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100);
        }
        double turnoverRateThanOldTime = 0.0;
        if (inquiryCountLast > 0) {
            turnoverRateThanOldTime = new BigDecimal(turnoverCountLast).divide(new BigDecimal(inquiryCountLast),
                    2, BigDecimal.ROUND_HALF_UP).doubleValue() * 100;
        }

        if (resDO.getTurnoverRate() >= turnoverRateThanOldTime) {
            resDO.setTurnoverRateThanOldTimeUp(resDO.getTurnoverRate() - turnoverRateThanOldTime);
        } else {
            resDO.setTurnoverRateThanOldTimeDown(turnoverRateThanOldTime - resDO.getTurnoverRate());
        }

        BigDecimal recycleAmount = BigDecimal.ZERO, recycleAmountLast = BigDecimal.ZERO;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            recycleAmount = recycleOrderMapper.queryRecycleAmountForTimeShop(bo.getStartTime(),
                    bo.getEndTime(), null, null, user.getCompanyId());
            if (recycleAmount == null) recycleAmount = BigDecimal.ZERO;
            recycleAmountLast = recycleOrderMapper.queryRecycleAmountForTimeShop(lastStartTime,
                    bo.getStartTime(), null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            recycleAmount = recycleOrderMapper.queryRecycleAmountForTimeShop(bo.getStartTime(),
                    bo.getEndTime(), bo.getShopId(), null, null);
            if (recycleAmount == null) recycleAmount = BigDecimal.ZERO;
            recycleAmountLast = recycleOrderMapper.queryRecycleAmountForTimeShop(lastStartTime,
                    bo.getStartTime(), bo.getShopId(), null, null);
        }

        if (recycleAmountLast == null) recycleAmountLast = BigDecimal.ZERO;
        resDO.setRecycleAmount(recycleAmount);
        if (recycleAmount.compareTo(recycleAmountLast) > 0) {
            if (recycleAmountLast.compareTo(BigDecimal.ZERO) == 0) {
                resDO.setRecycleAmountThanOldTimeUp(recycleAmount.intValue());
            } else {
                resDO.setRecycleAmountThanOldTimeUp(recycleAmount.subtract(recycleAmountLast).divide(recycleAmountLast).intValue());
            }
        } else if (recycleAmount.compareTo(recycleAmountLast) < 0) {
            resDO.setRecycleAmountThanOldTimeDown(recycleAmountLast.subtract(recycleAmount).divide(recycleAmountLast).intValue());
        } else {
            resDO.setRecycleAmountThanOldTimeUp(0);
        }

        BigDecimal recycleAvgAmount = BigDecimal.ZERO, recycleAvgAmountLast = BigDecimal.ZERO;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            recycleAvgAmount = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(bo.getStartTime(),
                    bo.getEndTime(), null, null, user.getCompanyId());
            if (recycleAvgAmount == null) recycleAvgAmount = BigDecimal.ZERO;
            else recycleAvgAmount = recycleAvgAmount.setScale(0, BigDecimal.ROUND_HALF_UP);
            recycleAvgAmountLast = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(lastStartTime,
                    bo.getStartTime(), null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            recycleAvgAmount = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(bo.getStartTime(),
                    bo.getEndTime(), bo.getShopId(), null, null);
            if (recycleAvgAmount == null) recycleAvgAmount = BigDecimal.ZERO;
            else recycleAvgAmount = recycleAvgAmount.setScale(0, BigDecimal.ROUND_HALF_UP);
            recycleAvgAmountLast = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(lastStartTime,
                    bo.getStartTime(), bo.getShopId(), null, null);
        }

        if (recycleAvgAmountLast == null) recycleAvgAmountLast = BigDecimal.ZERO;
        else recycleAvgAmountLast = recycleAvgAmountLast.setScale(0, BigDecimal.ROUND_HALF_UP);
        resDO.setRecycleAverageAmount(recycleAvgAmount);
        if (recycleAvgAmount.compareTo(recycleAvgAmountLast) > 0) {
            if (recycleAvgAmountLast.compareTo(BigDecimal.ZERO) == 0) {
                resDO.setRecycleAverageAmountThanOldTimeUp(recycleAvgAmount.intValue());
            } else {
                resDO.setRecycleAverageAmountThanOldTimeUp(recycleAvgAmount.subtract(recycleAvgAmountLast).divide(recycleAvgAmountLast).intValue());
            }
        } else if (recycleAmount.compareTo(recycleAmountLast) < 0) {
            resDO.setRecycleAverageAmountThanOldTimeDown(recycleAvgAmountLast.subtract(recycleAvgAmount).divide(recycleAvgAmountLast).intValue());
        } else {
            resDO.setRecycleAverageAmountThanOldTimeUp(0);
        }

        return AjaxResult.success(resDO);
    }

    @Override
    public AjaxResult updateRateOpen(Integer isOpen) {
        User user = mobileBaseService.hasLogin();
        Company company = companyMapper.selectById(user.getCompanyId());
        if (company == null) {
            return AjaxResult.error("没有该门店信息，设置失败");
        }
        company.setRateOpen(isOpen);
        return companyMapper.updateById(company) > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    public AjaxResult createOrUpdatePriceDown(PriceDownFormula bo) {
        User user = mobileBaseService.hasLogin();
        int num = 0;
        if (ObjectUtils.isEmpty(bo.getId())) {
            //新增
            bo.setCompanyId(user.getCompanyId());
            num = priceDownFormulaMapper.insert(bo);
        } else {
            num = priceDownFormulaMapper.updateById(bo);
        }
        return num > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    @Override
    public AjaxResult deletePriceDown(Integer id) {
        mobileBaseService.hasLogin();

        return priceDownFormulaMapper.deleteById(id) > 0 ? AjaxResult.success() : AjaxResult.error("删除失败");
    }

    @Override
    public AjaxResult queryPriceDownList() {
        User user = mobileBaseService.hasLogin();
        JSONObject jsonObject = new JSONObject();
        QueryWrapper<PriceDownFormula> wrapper = new QueryWrapper<>();
        wrapper.eq("company_id", user.getCompanyId());
        jsonObject.put("list", priceDownFormulaMapper.selectList(wrapper));
        Company company = companyMapper.selectById(user.getCompanyId());
        jsonObject.put("rate_open", company.getRateOpen());
        return AjaxResult.success(jsonObject);
    }

    @Override
    public AjaxResult queryEnterprise() {
        User user = mobileBaseService.hasLogin();
        ShopEnterpriseVo resDO = new ShopEnterpriseVo();
        ShopStatisticsVo statisticsVo = new ShopStatisticsVo();
        //今日开始结束时间
        DateTime todayBegin = DateUtil.beginOfDay(new Date());
        DateTime todayEnd = DateUtil.endOfDay(new Date());
        //昨日开始结束时间
        Calendar c = Calendar.getInstance();
        c.setTime(todayBegin);
        c.add(Calendar.DAY_OF_MONTH, -1);
        Date yesterdayBegin = c.getTime();
        c.setTime(todayEnd);
        c.add(Calendar.DAY_OF_MONTH, -1);
        Date yesterdayEndDay = c.getTime();

        Integer inquiryCount = 0, inquiryCountLast = 0;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            inquiryCount = inquiryOrderMapper.queryInquiryCountForTimeShop(todayBegin,
                    todayEnd, null, null, user.getCompanyId());
            inquiryCountLast = inquiryOrderMapper.queryInquiryCountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            inquiryCount = inquiryOrderMapper.queryInquiryCountForTimeShop(todayBegin,
                    todayEnd, user.getStoreId(), null, null);
            inquiryCountLast = inquiryOrderMapper.queryInquiryCountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, user.getStoreId(), null, null);
        } else if (UserTypeEnum.SHOP_OPERATOR.code().equals(user.getType())) {
            inquiryCount = inquiryOrderMapper.queryInquiryCountForTimeShop(todayBegin,
                    todayEnd, null, user.getId(), null);
            inquiryCountLast = inquiryOrderMapper.queryInquiryCountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, null, user.getId(), null);
        } else {
            return AjaxResult.error("权限不足");
        }

        statisticsVo.setInquiryCount(inquiryCount);
        if (inquiryCount > inquiryCountLast) {
            if (inquiryCountLast == 0) {
                statisticsVo.setInquiryCountThanOldTimeUp(inquiryCount);
            } else {
                statisticsVo.setInquiryCountThanOldTimeUp(Math.round((float) (inquiryCount - inquiryCountLast) / (float) inquiryCountLast));
            }
        } else if (inquiryCount < inquiryCountLast) {
            statisticsVo.setInquiryCountThanOldTimeUpDown(Math.round((float) (inquiryCountLast - inquiryCount) / (float) inquiryCountLast));
        } else {
            statisticsVo.setInquiryCountThanOldTimeUp(0);
        }

        Integer turnoverCount = 0, turnoverCountLast = 0;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            turnoverCount = recycleOrderMapper.queryFinishCountForTimeShop(todayBegin,
                    todayEnd, null, null, user.getCompanyId());
            turnoverCountLast = recycleOrderMapper.queryFinishCountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            turnoverCount = recycleOrderMapper.queryFinishCountForTimeShop(todayBegin,
                    todayEnd, user.getStoreId(), null, null);
            turnoverCountLast = recycleOrderMapper.queryFinishCountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, user.getStoreId(), null, null);
        } else if (UserTypeEnum.SHOP_OPERATOR.code().equals(user.getType())) {
            turnoverCount = recycleOrderMapper.queryFinishCountForTimeShop(todayBegin,
                    todayEnd, null, user.getId(), null);
            turnoverCountLast = recycleOrderMapper.queryFinishCountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, null, user.getId(), null);
        }

        statisticsVo.setTurnover(turnoverCount);
        if (turnoverCount > turnoverCountLast) {
            if (turnoverCountLast == 0) {
                statisticsVo.setTurnoverThanOldTimeUp(turnoverCount);
            } else {
                statisticsVo.setTurnoverThanOldTimeUp(Math.round((float) (turnoverCount - turnoverCountLast) / (float) turnoverCountLast));
            }
        } else if (turnoverCount < turnoverCountLast) {
            statisticsVo.setTurnoverThanOldTimeDown(Math.round((float) (turnoverCountLast - turnoverCount) / (float) turnoverCountLast));
        } else {
            statisticsVo.setTurnoverThanOldTimeUp(0);
        }

        if (inquiryCount > 0) {
            statisticsVo.setTurnoverRate(new BigDecimal(turnoverCount).divide(new BigDecimal(inquiryCount),
                    2, RoundingMode.HALF_UP).doubleValue() * 100);
        }
        if (inquiryCountLast > 0) {
            statisticsVo.setTurnoverRate(new BigDecimal(turnoverCountLast).divide(new BigDecimal(inquiryCountLast),
                    2, RoundingMode.HALF_UP).doubleValue() * 100);
        }

        BigDecimal recycleAmount = BigDecimal.ZERO, recycleAmountLast = BigDecimal.ZERO;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            recycleAmount = recycleOrderMapper.queryRecycleAmountForTimeShop(todayBegin,
                    todayEnd, null, null, user.getCompanyId());
            recycleAmountLast = recycleOrderMapper.queryRecycleAmountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            recycleAmount = recycleOrderMapper.queryRecycleAmountForTimeShop(todayBegin,
                    todayEnd, user.getStoreId(), null, null);
            recycleAmountLast = recycleOrderMapper.queryRecycleAmountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, user.getStoreId(), null, null);
        } else if (UserTypeEnum.SHOP_OPERATOR.code().equals(user.getType())) {
            recycleAmount = recycleOrderMapper.queryRecycleAmountForTimeShop(todayBegin,
                    todayEnd, null, user.getId(), null);
            recycleAmountLast = recycleOrderMapper.queryRecycleAmountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, null, user.getId(), null);
        }

        recycleAmountLast = ObjectUtils.isEmpty(recycleAmountLast) ? new BigDecimal(0) : recycleAmountLast;
        recycleAmount = ObjectUtils.isEmpty(recycleAmount) ? new BigDecimal(0) : recycleAmount;
        statisticsVo.setRecycleAmount(recycleAmount);
        if (recycleAmount.compareTo(recycleAmountLast) > 0) {
            if (recycleAmountLast.compareTo(BigDecimal.ZERO) == 0) {
                statisticsVo.setTurnoverThanOldTimeUp(recycleAmount.intValue());
            } else {
                statisticsVo.setTurnoverThanOldTimeUp(recycleAmount.subtract(recycleAmountLast).divide(recycleAmountLast, RoundingMode.HALF_UP).intValue());
            }
        } else if (recycleAmount.compareTo(recycleAmountLast) < 0) {
            statisticsVo.setTurnoverThanOldTimeDown(recycleAmountLast.subtract(recycleAmount).divide(recycleAmountLast, RoundingMode.HALF_UP).intValue());
        } else {
            statisticsVo.setTurnoverThanOldTimeUp(0);
        }

        BigDecimal recycleAvgAmount = BigDecimal.ZERO, recycleAvgAmountLast = BigDecimal.ZERO;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            recycleAvgAmount = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(todayBegin,
                    todayEnd, null, null, user.getCompanyId());
            recycleAvgAmountLast = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            recycleAvgAmount = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(todayBegin,
                    todayEnd, user.getStoreId(), null, null);
            recycleAvgAmountLast = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, user.getStoreId(), null, null);
        } else if (UserTypeEnum.SHOP_OPERATOR.code().equals(user.getType())) {
            recycleAvgAmount = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(todayBegin,
                    todayEnd, null, user.getId(), null);
            recycleAvgAmountLast = recycleOrderMapper.queryRecycleAvgAmountForTimeShop(yesterdayBegin,
                    yesterdayEndDay, null, user.getId(), null);
        }

        recycleAvgAmount = ObjectUtils.isEmpty(recycleAvgAmount) ? new BigDecimal(0) : recycleAvgAmount;
        recycleAvgAmountLast = ObjectUtils.isEmpty(recycleAvgAmountLast) ? new BigDecimal(0) : recycleAvgAmountLast;
        statisticsVo.setRecycleAverageAmount(recycleAvgAmount);
        if (recycleAvgAmount.compareTo(recycleAvgAmountLast) > 0) {
            if (recycleAvgAmountLast.compareTo(BigDecimal.ZERO) == 0) {
                statisticsVo.setRecycleAverageAmountThanOldTimeUp(recycleAvgAmount.intValue());
            } else {
                statisticsVo.setRecycleAverageAmountThanOldTimeUp(recycleAvgAmount.subtract(recycleAvgAmountLast).divide(recycleAvgAmountLast, RoundingMode.HALF_UP).intValue());
            }
        } else if (recycleAmount.compareTo(recycleAmountLast) < 0) {
            statisticsVo.setRecycleAverageAmountThanOldTimeDown(recycleAvgAmountLast.subtract(recycleAvgAmount).divide(recycleAvgAmountLast, RoundingMode.HALF_UP).intValue());
        } else {
            statisticsVo.setRecycleAverageAmountThanOldTimeUp(0);
        }
        resDO.setStatisticsVo(statisticsVo);

        Integer sumInquiryCount = 0, sumTurnoverCount = 0;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            sumInquiryCount = inquiryOrderMapper.queryInquiryCountForTimeShop(null,
                    null, null, null, user.getCompanyId());
            sumTurnoverCount = recycleOrderMapper.queryFinishCountForTimeShop(null,
                    null, null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            sumInquiryCount = inquiryOrderMapper.queryInquiryCountForTimeShop(null,
                    null, user.getStoreId(), null, null);
            sumTurnoverCount = recycleOrderMapper.queryFinishCountForTimeShop(null,
                    null, user.getStoreId(), null, null);
        } else if (UserTypeEnum.SHOP_OPERATOR.code().equals(user.getType())) {
            sumInquiryCount = inquiryOrderMapper.queryInquiryCountForTimeShop(null,
                    null, null, user.getId(), null);
            sumTurnoverCount = recycleOrderMapper.queryFinishCountForTimeShop(null,
                    null, null, user.getId(), null);
        }

        resDO.setSumInquiryCount(sumInquiryCount);
        resDO.setSumTurnover(sumTurnoverCount);

        if (sumInquiryCount == 0) {
            resDO.setSumTurnoverRate(new BigDecimal(sumTurnoverCount).doubleValue() * 100);
        } else {
            resDO.setSumTurnoverRate(new BigDecimal(sumTurnoverCount).divide(new BigDecimal(sumInquiryCount),
                    2, RoundingMode.HALF_UP).doubleValue() * 100);
        }

        BigDecimal sumRecycleAmount = BigDecimal.ZERO;
        if (UserTypeEnum.COMPANY.code().equals(user.getType())) {
            sumRecycleAmount = recycleOrderMapper.queryRecycleAmountForTimeShop(null,
                    null, null, null, user.getCompanyId());
        } else if (UserTypeEnum.SHOP_OWNER.code().equals(user.getType())) {
            sumRecycleAmount = recycleOrderMapper.queryRecycleAmountForTimeShop(null,
                    null, user.getStoreId(), null, null);
        } else if (UserTypeEnum.SHOP_OPERATOR.code().equals(user.getType())) {
            sumRecycleAmount = recycleOrderMapper.queryRecycleAmountForTimeShop(null,
                    null, null, user.getId(), null);
        }

        resDO.setSumRecycleAmount(sumRecycleAmount == null ? BigDecimal.ZERO : sumRecycleAmount);

        return AjaxResult.success(resDO);
    }

    @Override
    public AjaxResult queryMsgDialogueList(Long inquiryOrderId) {
        LambdaQueryWrapper<MsgDialogueOrder> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(MsgDialogueOrder::getInquiryOrderId, inquiryOrderId);
        lambdaQuery.orderByAsc(MsgDialogueOrder::getSendTime);
        return AjaxResult.success(msgDialogueMapper.selectVoList(lambdaQuery));
    }

    /**
     * 保存前的数据转换
     */
    private VerifyModelOption tranEntityBeforeSave(VerifyModelOptionBo bo) {
        //TODO 做一些数据转换
        VerifyModelOption verifyModelOption = new VerifyModelOption();
        BeanUtils.copyProperties(bo, verifyModelOption);
        return verifyModelOption;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(InquiryOrder entity) {
        //TODO 做一些数据校验,如唯一约束
        if (StringUtils.isEmpty(entity.getIemi())) {
            throw new ServiceException("ieml不能为空");
        }
        if (StringUtils.isEmpty(entity.getModelName())) {
            throw new ServiceException("机型名称不能为空");
        }
    }

    /**
     * 保存前的数据转换
     */
    private InquiryOrder tranEntityBeforeSave(InquiryOrderBo bo) {
        //TODO 做一些数据转换
        InquiryOrder inquiryOrder = new InquiryOrder();
        BeanUtils.copyProperties(bo, inquiryOrder);
        return inquiryOrder;
    }
}
